import java.util.*;

public class SetManipulator {
	private ArrayList<String> derivable;

	public SetManipulator() {
		derivable = new ArrayList<String>();
	}

	public ArrayList<ArrayList<String>> computeMaxSets(ArrayList<String> r,
			ArrayList<String> r_s, ArrayList<FuncDep> fd) {
		ArrayList<ArrayList<String>> maxSets = new ArrayList<ArrayList<String>>();

		for (int i = 0; i < r.size(); i++) {
			ArrayList<String> maxSet = new ArrayList<String>();

			// Finding the derivable set
			this.derivable.clear();
			findDerivables(r.get(i), r_s, fd);

			// Finding the max set
			for (int j = 0; j < r.size(); j++) {
				if (j != i && !derivable.contains(r.get(j))) {
					maxSet.add(r.get(j));
				}
			}

			maxSets.add(maxSet);
		}

		return maxSets;
	}

	private void findDerivables(String att, ArrayList<String> r_s,
			ArrayList<FuncDep> fd) {
		for (int i = 0; i < fd.size(); i++) {
			String from = fd.get(i).getFrom();
			String to = fd.get(i).getTo();

			if (to.equals(att) && !this.derivable.contains(from)) {
				this.derivable.add(from);
				// fd.remove(i--);
				if (r_s.contains(from)) {
					findDerivables(from, r_s, fd);
				}
			}
		}
	}

	public ArrayList<String> union2(ArrayList<String> z, ArrayList<String> rs_X) {
		ArrayList<String> union = new ArrayList<String>();

		for (int i = 0; i < z.size(); i++) {
			if (!union.contains(z.get(i))) {
				union.add(z.get(i));
			}
		}

		for (int i = 0; i < rs_X.size(); i++) {
			if (!union.contains(rs_X.get(i))) {
				union.add(rs_X.get(i));
			}
		}

		return union;
	}

	public ArrayList<String> subtract(ArrayList<String> big,
			ArrayList<String> small) {
		ArrayList<String> result = new ArrayList<String>();

		for (int i = 0; i < big.size(); i++) {
			if (!small.contains(big.get(i))) {
				result.add(big.get(i));
			}
		}

		return result;
	}

	public ArrayList<String> union3(ArrayList<String> x, ArrayList<String> z,
			ArrayList<String> r_s) {
		ArrayList<String> union = new ArrayList<String>();

		for (int i = 0; i < x.size(); i++) {
			if (!union.contains(x.get(i))) {
				union.add(x.get(i));
			}
		}

		for (int i = 0; i < z.size(); i++) {
			if (!union.contains(z.get(i))) {
				union.add(z.get(i));
			}
		}

		for (int i = 0; i < r_s.size(); i++) {
			if (!union.contains(r_s.get(i))) {
				union.add(r_s.get(i));
			}
		}

		return union;
	}

	public boolean belongs(ArrayList<String> small, ArrayList<String> big) {
		for (int i = 0; i < small.size(); i++) {
			if (!big.contains(small.get(i))) {
				return false;
			}
		}
		return true;
	}
}
